--[[
Copyright:www.vxinyou.com
Author:马柏威
CreateTime:2014-12-11
Description:场景对象类

Modifier:J杰
ModifyTime:2014-2-5
Comment:改名场景对象管理器，专门管理场景中的GameObj和LivingObj

]]

local clsSceneObjMgr = Class("lua/util/clsInstance.lua"):Inherit()

------------------------------public------------------------------
------------------------------------------------------------------
--Output:讲对象加入场景管理器中
function clsSceneObjMgr:addObject(obj)
	--如果是活物，加入活物列表中
	if obj:isLivingObject() == true then
		local finded = false
		for k,v in ipairs (self.livingObjs) do
			if v == ojb then
				finded = true
				break
			end
		end
		if finded == false then
			table.insert(self.livingObjs,obj)
			--每加入一个livingObj，就算一下组
			self:calculateAllGroup()
		end
	--如果只是游戏对象，加入对象列表中
	else
		local finded = false
		for k,v in ipairs (self.gameObjs) do
			if v == ojb then
				finded = true
				break
			end
		end
		if finded == false then
			table.insert(self.gameObjs,obj)
		end
	end
end

--Output:从场景中删除对象
function clsSceneObjMgr:removeObject(obj)
	if obj:isLivingObject() == true then
		for k,v in ipairs (self.livingObjs) do
			if v == obj then
				table.remove(self.livingObjs,k)
				v:destroy() -- 从场景中移除
				--每删除一个livingObj，就算一下组
				self:calculateAllGroup()
				break
			end
		end
	else
		for k,v in ipairs (self.gameObjs) do
			if v == obj then
				table.remove(self.gameObjs,k)
				v:destroy() -- 从场景中移除
				break
			end
		end
	end
end

--Output:从场景中删除所有
function clsSceneObjMgr:removeAllObject()
	--[[for k,v in ipairs (self.livingObjs) do
		self:removeObject(v)
	end
	for k,v in ipairs (self.gameObjs) do
		self:removeObject(v)
	end--]]
	for i = #self.livingObjs, 1, -1 do
		self.livingObjs[i]:destroy()
		table.remove( self.livingObjs, i )
	end
	for i = #self.gameObjs, 1, -1 do
		self.gameObjs[i]:destroy()
		table.remove( self.gameObjs, i )
	end
	--删除livingObj后，就算一下组
	self:calculateAllGroup()
end

--Function:查找指定对象是否加在本场景中
function clsSceneObjMgr:findLivingObject(obj)
	local finded = false
	if table.getn(self.livingObjs) > 0 then
		for k,v in ipairs (self.livingObjs) do
			if v == ojb then
				finded = true
				break
			end
		end
	end
	return finded
end

--Output:获得所有对象
function clsSceneObjMgr:getLivingObjects()
	return self.livingObjs
end

--Output:获取队友
function clsSceneObjMgr:getAllTeammateByObj(obj)
	if obj:getGroupID() then
		return self:getAllTeammateByGroupID(obj:getGroupID())
	end
	return nil
end

function clsSceneObjMgr:getAllTeammateByGroupID(groupID)
--[[
	local Objs = {}
	for k,v in ipairs(self.livingObjs) do
		if v:getGroupID() == groupID then
				table.insert(Objs,v)
			end
		end
	end
	return Objs
--]]
	if self.objGroup[groupID] then
		return self.objGroup[groupID]
	else
		return {}
	end
end

--Output:获取对手
function clsSceneObjMgr:getAllEnemyByObj(obj)
	if obj:getGroupID() then
		return self:getAllEnemyByGroupID(obj:getGroupID())
	end
	return nil
end

function clsSceneObjMgr:getAllEnemyByGroupID(groupID)
--[[	
	local Objs = {}
	for k,v in ipairs(self.livingObjs) do
		if v:getGroupID() ~= groupID then
				table.insert(Objs,v)
			end
		end
	end
	return Objs
	--]]
	local Objs = {}
	for k,v in pairs(self.objGroup) do
		if k ~= groupID then
			if not MOD_UTIL.isTableHasElement(Objs) then
				table.merge(Objs,v)
			end
		end
	end
	return Objs
end 

--function:改变某个obj的GroupID后，再算组
function clsSceneObjMgr:changeObjGroup(obj,newGroupID)
	obj:setGroupID(newGroupID)
	self:calculateAllGroup()
end
	

--计算分组:根据当前的GroupID，分出各组
--[[
这个方法可能有可能的几种情况会调用
1.可以是每帧调用，每帧都重新计算每个人的组，优点是每次攻击前都会算组，会保持这个组信息是最新的，缺点是每次都会去遍历livingObjs消耗内存
2.可以是进入战斗后只算一次，因为大部分时候大家的组的一开始就定好的，算一次就行了，有点是大部分情况下只算一次，
缺点：	1.如果出现有能改组的技能怎么处理----可以在那个技能改变组ID后再调用一次这个方法
		2.对象挂了或者退出了怎么处理----- 可以在离开场景中的方法时再调用一次这个方法
		3.战斗中有新的对象乱入怎么处理 ---- 同上
		4.如果123都做到的话，这么多个地方都调用这个的话，耦合度有点高
		
目前尝试第2种方式，任何LivingObj加入跟删除的时候调用这个方法，这个封装一个改变组ID的方法，改完也会算一次组
--]]
function clsSceneObjMgr:calculateAllGroup()
	self.objGroup = nil
	self.objGroup = {}
	if #self.livingObjs == 0 then
		return
	end
	for k,v in ipairs(self.livingObjs) do
		if (v:getGroupID() ~= nil) and (v:getGroupID() ~= 0) then
			self:addObj2Group(v:getGroupID(),v)
		end
	end
end

--[[
--Output:获取指定对象能够攻击的目标列表
function clsSceneObjMgr:getBeAttackObjects(obj)
	local livingObjs = {}
	local rcObjAttack = getAttackRange(obj)
	for k,v in ipairs(self.livingObjs) do
		if v ~= obj then
			if v:isLivingObject() == true then
				local rcObjBeAttack = v:getBeAttackRange()
				if collisionDetection(rcObjAttack,rcObjBeAttack) == true then
					table.insert(livingObjs,v)
				end
			end
		end
	end
	return livingObjs
end--]]

function getClass()
	return clsSceneObjMgr      
end

------------------------------private-----------------------------
------------------------------------------------------------------
--function:new
function clsSceneObjMgr:New()
	--场景中的活物物体列表
	self.livingObjs = {}
	--场景中的游戏物体列表
	self.gameObjs = {}
	--分组信息,用一个2维数组来保存分组，不需要每次都去遍历livingObjs
	self.objGroup = {}
	return self
end

--function：私有方法：把一个对象加入组中，如果这个组不存在，新建一个组
function clsSceneObjMgr:addObj2Group(groupID,obj)
	--根据GroupID获取当前有没有这个组
	if self.objGroup[groupID] == nil then  ---没有，新建组，把obj加入助里
		local group = {}
		table.insert(group,obj)
		self.objGroup[groupID] = group
	else							--有，找到组，把obj加入组里		
		table.insert(self.objGroup[groupID],obj)
	end
end
